/*
 * lcd.c:
 *	Text-based LCD driver.
 *	This is designed to drive the parallel interface LCD drivers
 *	based in the Hitachi HD44780U controller and compatables.
 *
 *	This test program assumes the following:
 *
 *	8-bit displays:
 *		GPIO 0-7 is connected to display data pins 0-7.
 *		GPIO 11 is the RS pin.
 *		GPIO 10 is the Strobe/E pin.
 *
 *	For 4-bit interface:
 *		GPIO 4-7 is connected to display data pins 4-7.
 *		GPIO 11 is the RS pin.
 *		GPIO 10 is the Strobe/E pin.
 *
 * Copyright (c) 2012-2013 Gordon Henderson.
 ***********************************************************************
 * This file is part of wiringPi:
 *	https://projects.drogon.net/raspberry-pi/wiringpi/
 *
 *    wiringPi is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU Lesser General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    wiringPi is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public License
 *    along with wiringPi.  If not, see <http://www.gnu.org/licenses/>.
 ***********************************************************************
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <dirent.h>
#include <linux/input.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/time.h>
#include <termios.h>
#include <signal.h>
#include <curl/curl.h>
#include <curl/easy.h>

#include <unistd.h>
#include <string.h>
#include <time.h>

#include <wiringPi.h>
#include <lcd.h>

#ifndef	TRUE
#  define	TRUE	(1==1)
#  define	FALSE	(1==2)
#endif


/* function prototypes to define later */
char *do_web_request(char *url);
size_t static write_callback_func(void *buffer,
                        size_t size,
                        size_t nmemb,
                        void *userp);


// Global lcd handle:

static int lcdHandle ;



char *trim(char *str)
{
  char *end;

  // Trim leading space
  while(isspace(*str)) str++;

  if(*str == 0)  // All spaces?
    return str;

  // Trim trailing space
  end = str + strlen(str) - 1;
  while(end > str && isspace(*end)) end--;

  // Write new null terminator
  *(end+1) = 0;

  return str;
}



/*
 * usage:
 *********************************************************************************
 */

int usage (const char *progName)
{
  fprintf (stderr, "Usage: %s bits cols rows\n", progName) ;
  return EXIT_FAILURE ;
}


/*
 * scrollMessage:
 *********************************************************************************
 */

static const char *message =
  "                    "
  "Wiring Pi by Gordon Henderson. HTTP://WIRINGPI.COM/"
  "                    " ;

void scrollMessage (int line, int width)
{
  char buf [32] ;
  static int position = 0 ;
  static int timer = 0 ;

  if (millis () < timer)
    return ;

  timer = millis () + 200 ;

  strncpy (buf, &message [position], width) ;
  buf [width] = 0 ;
  lcdPosition (lcdHandle, 0, line) ;
  lcdPuts     (lcdHandle, buf) ;

  if (++position == (strlen (message) - width))
    position = 0 ;
}



/*
 * The works
 *********************************************************************************
 */

int main (int argc, char *argv[])
{
  int i ;
  int rows; 
  int cols;

  struct tm *t ;
  time_t tim ;

  char buf [32] ;

	struct input_event ev[64];
	int fd, rd, value, size = sizeof (struct input_event);
	char name[256] = "Unknown";
	char device[256] = "/dev/input/event0";

	if ((getuid()) != 0){
		printf ("You are not root! This will not work. Exiting...\n");
		exit(0);
	}


	if ((fd = open(device, O_RDONLY)) == -1){
		printf ("%s is not a vaild device. Exiting...\n", device);
		exit(0);
	}

	//grab device exclusively
	ioctl(fd, EVIOCGRAB, 1);
	//Print Device Name
	ioctl(fd, EVIOCGNAME (sizeof (name)), name);
	//printf("Reading From : %s (%s)\n", device, name);

	char buffer[50];
	int cursor = 0;

	// ========================



  printf ("Raspberry Pi LCD test\n") ;
  printf ("=====================\n") ;

  cols = 16; // atoi (argv [2]) ;
  rows = 2; //atoi (argv [3]) ;

  if (!((rows == 1) || (rows == 2) || (rows == 4)))
  {
    fprintf (stderr, "%s: rows must be 1, 2 or 4\n", argv [0]) ;
    return EXIT_FAILURE ;
  }

  if (!((cols == 16) || (cols == 20)))
  {
    fprintf (stderr, "%s: cols must be 16 or 20\n", argv [0]) ;
    return EXIT_FAILURE ;
  }

  wiringPiSetup () ;

  lcdHandle = lcdInit (rows, cols, 4, 6, 5, 4, 0, 2, 3,0,0,0,0) ;

  if (lcdHandle < 0) {
    fprintf (stderr, "%s: lcdInit failed\n", argv [0]) ;
    return -1 ;
  }

  lcdClear(lcdHandle);

  lcdPosition (lcdHandle, 0, 0);
  lcdClear(lcdHandle);
  lcdPuts(lcdHandle, "Fantasieland") ;



//  unsigned long tsSend = time(NULL);
// use sigaction als je niet wilt wachten op het event

  while (1) {
/*
		unsigned long tsNow = time(NULL);
		if ((tsSend + 10) < tsNow) {
			tsSend = time(NULL);
			printf("clear  %u %u\n", tsNow, tsSend);
			
			lcdPosition (lcdHandle, 0, 0);
			lcdClear(lcdHandle);

		} else {
					printf("t  %u %u\n", tsNow, tsSend);
		}
*/
 
	  if ((rd = read (fd, ev, size * 64)) < size){
			perror("read() failed. Exiting...\n");
			exit(0);
		}

		value = ev[0].value;

		if(ev[1].code > 12 && ev[1].code != 28)
			continue;

		if(value == ' ' || ev[1].value != 1 || ev[1].type != 1)
			continue;

		if(ev[1].code == 28){ //Enter
			if(cursor == 0)
				continue;

			buffer[cursor] = '\0';

			char url[128];
			// sendString(buffer, cursor);
			sprintf (url, "http://192.168.0.10/scan.php?a=%s", buffer);
			printf("OUT %s\n", trim(url));
			char *content = NULL;

			content = do_web_request(url);

			printf("IN  %s\n", trim(content));

//			tsSend = time(NULL);
//			printf("now  %u\n", tsSend);

			lcdPosition (lcdHandle, 0, 0);
			lcdClear(lcdHandle);
			lcdPuts     (lcdHandle, trim(content)) ;

			cursor = 0;
		} else {
			int zahl = ev[1].code - 1;

			if(zahl == 10) //zero
				zahl = 0;

			zahl += 48; //make ASCII

			buffer[cursor] = zahl;
			cursor++;
		}



  }

  return 0 ;
}


/* the function to return the content for a url */
char *do_web_request(char *url)
{
    /* keeps the handle to the curl object */
    CURL *curl_handle = NULL;
    /* to keep the response */
    char *response = NULL;

    /* initializing curl and setting the url */
    curl_handle = curl_easy_init();
    curl_easy_setopt(curl_handle, CURLOPT_URL, url);
    curl_easy_setopt(curl_handle, CURLOPT_HTTPGET, 1);

    /* follow locations specified by the response header */
    curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);

    /* setting a callback function to return the data */
    curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_callback_func);

    /* passing the pointer to the response as the callback parameter */
    curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &response);

    /* perform the request */
    curl_easy_perform(curl_handle);

    /* cleaning all curl stuff */
    curl_easy_cleanup(curl_handle);

    return response;
}

/* the function to invoke as the data recieved */
size_t static write_callback_func(void *buffer,
                        size_t size,
                        size_t nmemb,
                        void *userp)
{
    char **response_ptr =  (char**)userp;

    /* assuming the response is a string */
    *response_ptr = strndup(buffer, (size_t)(size *nmemb));
    return (size_t)(size *nmemb);
}


